#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @File    : interface.model.py
# @Note    : "强化学习模型"窗口界面

from PyQt5.QtGui import QIcon, QPixmap
from PyQt5.QtWidgets import QMainWindow, QFileDialog, QMessageBox
from PyQt5.uic import loadUiType

ui, _ = loadUiType("./resource/ui/model.ui")


# 强化学习模型界面
class modelDialog(QMainWindow, ui):
    def __init__(self):
        QMainWindow.__init__(self)
        self.setupUi(self)
        self.setWindowIcon(QIcon("../resource/icon/about.png"))
        self.setWindowTitle("深度强化学习模型")
        self.setFixedSize(self.width(), self.height())
        self.label_network1.setScaledContents(True)
        self.label_network2.setScaledContents(True)
        self.label_network3.setScaledContents(True)
        self.label_network4.setScaledContents(True)
        self.label_network5.setScaledContents(True)
        self.label_network6.setScaledContents(True)
        self.label_network7.setScaledContents(True)
        self.label_network8.setScaledContents(True)
        self.label_layer1.setScaledContents(True)
        self.label_layer2.setScaledContents(True)
        self.label_layer3.setScaledContents(True)
        self.label_layer4.setScaledContents(True)
        self.label_activate1.setScaledContents(True)
        self.label_activate2.setScaledContents(True)
        self.label_activate3.setScaledContents(True)
        self.label_network1.setPixmap(QPixmap("./resource/icon/network_input.png"))
        self.label_network2.setPixmap(QPixmap("./resource/icon/network_hidden.png"))
        self.label_network3.setPixmap(QPixmap("./resource/icon/network_output.png"))
        self.label_network4.setPixmap(QPixmap("./resource/icon/network_activate.png"))
        self.label_network5.setPixmap(QPixmap("./resource/icon/network_kernel.png"))
        self.label_network6.setPixmap(QPixmap("./resource/icon/network_pool.png"))
        self.label_network7.setPixmap(QPixmap("./resource/icon/network_recu.png"))
        self.label_network8.setPixmap(QPixmap("./resource/icon/network_conv.png"))
        self.label_layer1.setPixmap(QPixmap("./resource/icon/network_input.png"))
        self.label_layer2.setPixmap(QPixmap("./resource/icon/network_hidden.png"))
        self.label_layer3.setPixmap(QPixmap("./resource/icon/network_hidden.png"))
        self.label_layer4.setPixmap(QPixmap("./resource/icon/network_output.png"))
        self.label_activate1.setPixmap(QPixmap("./resource/icon/network_activate.png"))
        self.label_activate2.setPixmap(QPixmap("./resource/icon/network_activate.png"))
        self.label_activate3.setPixmap(QPixmap("./resource/icon/network_activate.png"))
        # 按钮槽连接
        self.pushButton_import_plan.clicked.connect(self.import_plans)
        self.pushButton_generate_plan.clicked.connect(self.generate_plans)

    # 创建配时方案
    @staticmethod
    def create_plans(para, file, plan_num=-1):
        # 配时范围
        cycle_time = para[0]
        green_low = para[1]
        green_high = para[2]
        green_interval = para[3]
        amber_time = para[4]
        clearing_time = para[5]
        phase_num = len(clearing_time)
        loss_time = amber_time * phase_num + sum(clearing_time)
        try:
            with open(file, "a+") as f:
                f.truncate(0)
        except (IndexError, Exception):
            pass
        from itertools import permutations
        a = list(permutations(range(green_low, green_high + 1, green_interval), phase_num))
        plans = []
        unused_plan = 0
        for i in range(len(a)):
            if sum(a[i]) == cycle_time - loss_time:
                if plan_num < 0 or len(plans) < plan_num:
                    plan = [cycle_time, amber_time, clearing_time, list(a[i])]
                    plans.append(plan)
                    with open(file, "a+") as f:
                        line = "%s\n" % (str(plan))
                        f.write(line)
                else:
                    unused_plan += 1
        return plans, unused_plan

    def get_timing_para(self):
        phase_num = int(self.lineEdit_phase_num.text())
        cycle_time = int(self.lineEdit_cycle_time.text())
        clear_time = list(map(int, self.lineEdit_clear_time.text().split(",")))
        yellow = int(self.lineEdit_yellow.text())
        green_short = int(self.lineEdit_green_short.text())
        green_long = int(self.lineEdit_green_long.text())
        green_interval = int(self.lineEdit_green_interval.text())
        plan_num = int(self.lineEdit_plan_num.text())
        timming = [cycle_time, green_short, green_long, green_interval, yellow, clear_time]
        return timming, phase_num, plan_num

    def imshow_plans(self, info):
        self.textBrowser_plan_info.clear()
        for i in range(len(info)):
            if info[i] != "":
                self.textBrowser_plan_info.append(str(i + 1) + " ：  " + info[i] + "\n")

    def generate_plans(self):
        file = './model/txt/test_fix_plans.txt'
        reply = QFileDialog.getSaveFileName(self, '保存生成的配时文件', file, "文本(*.txt)")
        try:
            if reply[0]:
                with open(reply[0], "w") as f:
                    f.write("")
                timming, _, plans_num = self.get_timing_para()
                plans, unused_plan = self.create_plans(timming, reply[0], plans_num)
                QMessageBox.information(self, "提示", "共生成%d种可选配时方案, 还有%d种方案未使用" % (len(plans), unused_plan))
                with open(file, "r") as f:
                    info = f.read().split("\n")
                    self.imshow_plans(info)
                QMessageBox.information(self, "提示", "保存配时方案文件成功")
            else:
                QMessageBox.warning(self, "提示", "请选择正确的路径并确认")
        except (IndexError, Exception):
            QMessageBox.warning(self, "提示", "保存配时方案文件失败")

    def import_plans(self):
        reply = QFileDialog.getOpenFileName(self, '导入已存在的配时方案文件', './model/txt/', "文本(*.txt)")
        try:
            if reply[0]:
                with open(reply[0], "r") as f:
                    info = f.read().split("\n")
                    self.imshow_plans(info)
                num = len(info)
                for i in range(len(info)):
                    if info[i] == "":
                        num = i
                        break
                QMessageBox.information(self, "提示", "共导入%d种可选配时方案" % num)
                QMessageBox.information(self, "提示", "导入配时方案文件成功")
            else:
                QMessageBox.warning(self, "提示", "请选择正确的路径并确认")
        except (IndexError, Exception):
            QMessageBox.warning(self, "提示", "导入配时方案文件失败")

    # 加载网络模型参数设置
    def load_network_setting(self):
        ALGORITHM = self.comboBox_algorithm.currentText()
        LOSS = self.comboBox_loss.currentText()
        OPTIM = self.comboBox_optim.currentText()
        ACTIVATE = self.comboBox_activate.currentText()